package com.aidong.service;

/**
 * Created by john on 16-11-2.
 */

import com.aidong.cache.ItemCache;
import com.aidong.util.FuncUtil;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.stereotype.Service;

@Service
public class AliPayService {
    protected Logger log = Logger.getLogger(this.getClass());
    @Resource
    protected ItemCache cache;

    public boolean createPay(String barCode, String tradeNo, double money, String shopCode, StringBuilder alipayNo, StringBuilder msg) {
        DecimalFormat nf = new DecimalFormat("0.##");
        HashMap param = new HashMap();
        param.put("seller_email", this.getSetting("alipay.account"));
        param.put("out_trade_no", tradeNo);
        param.put("subject", "WillsPay");
        param.put("total_fee", nf.format(money));
        param.put("product_code", "BARCODE_PAY_OFFLINE");
        param.put("dynamic_id_type", "barcode");
        param.put("dynamic_id", barCode);
        param.put("it_b_pay", "2m");
        param.put("extend_params", "{\"STORE_ID\":\"" + shopCode + "\"}");
        Map ret = this.call("alipay.acquire.createandpay", (Map) param, msg);
        if (ret != null) {
            String rc = (String) ret.get("result_code");
            if (rc != null && ("ORDER_SUCCESS_PAY_SUCCESS".equalsIgnoreCase(rc) || "ORDER_SUCCESS_PAY_INPROCESS".equalsIgnoreCase(rc))) {
                if (alipayNo != null) {
                    alipayNo.append((String) ret.get("trade_no"));
                }

                if (msg != null) {
                    msg.append(rc);
                }

                return true;
            }

            if (msg != null) {
                if (ret.containsKey("detail_error_des")) {
                    msg.append((String) ret.get("detail_error_des"));
                } else if (ret.containsKey("detail_error_code")) {
                    msg.append((String) ret.get("detail_error_code"));
                } else {
                    msg.append(rc);
                }
            }
        }

        return false;
    }

    public int queryPay(String tradeNo, Map<String, String> rep, StringBuilder msg) {
        HashMap param = new HashMap();
        param.put("out_trade_no", tradeNo);
        Map ret = this.call("alipay.acquire.query", (Map) param, msg);
        if (ret != null) {
            if (rep != null) {
                rep.putAll(ret);
            }

            if ("SUCCESS".equalsIgnoreCase((String) ret.get("result_code"))) {
                String stat = (String) ret.get("trade_status");
                if (msg != null) {
                    msg.append(stat);
                }

                if (FuncUtil.strInArray(stat, new String[]{"TRADE_SUCCESS", "TRADE_PENDING", "TRADE_FINISHED"})) {
                    return 1;
                }

                if ("WAIT_BUYER_PAY".equalsIgnoreCase(stat)) {
                    return 0;
                }

                if ("TRADE_CLOSED".equalsIgnoreCase(stat)) {
                    return 3;
                }
            } else if (msg != null) {
                msg.append((String) ret.get("result_code"));
            }
        }

        return -1;
    }

    protected Map<String, String> call(String service, Map<String, String> param, StringBuilder msg) {
        HashMap retMap = null;
        String url = this.getSetting("alipay.callurl") + "?_input_charset=utf-8";
        if (param == null) {
            param = new HashMap();
        }

        ((Map) param).put("service", service);
        ((Map) param).put("partner", this.getSetting("alipay.partner"));
        ((Map) param).put("_input_charset", "utf-8");
        this.addSignParam((Map) param);
        StringBuilder sb = new StringBuilder();

        String e;
        for (Iterator rep = ((Map) param).keySet().iterator(); rep.hasNext(); sb.append(e).append("=").append(this.encode((String) ((Map) param).get(e)))) {
            e = (String) rep.next();
            if (sb.length() > 0) {
                sb.append("&");
            }
        }

        String rep1 = this.call(url, sb.toString(), msg);
        if (rep1 != null) {
            try {
                Document e2 = DocumentHelper.parseText(rep1);
                Element root = e2.getRootElement();
                if ("T".equalsIgnoreCase(root.element("is_success").getText())) {
                    retMap = new HashMap();
                    List ls = root.element("response").element("alipay").elements();
                    Iterator i$ = ls.iterator();

                    while (i$.hasNext()) {
                        Element e1 = (Element) i$.next();
                        retMap.put(e1.getName(), e1.getText());
                    }
                }
            } catch (Exception var13) {
                this.log.error("alipay response xml", var13);
                retMap = null;
                msg.append("返回数据无法解析");
            }
        }

        return retMap;
    }

    protected String call(String url, String data, StringBuilder msg) {
        String rep = null;

        try {
            URL e = new URL(url);
            HttpURLConnection http = (HttpURLConnection) e.openConnection();
            http.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows XP; DigExt)");
            http.setConnectTimeout(30000);
            http.setReadTimeout('\uea60');
            if (data != null && data.length() > 0) {
                http.setRequestMethod("POST");
                http.setDoOutput(true);
                OutputStream is = http.getOutputStream();
                is.write(data.getBytes("utf-8"));
                is.flush();
                is.close();
            } else {
                http.setRequestMethod("GET");
            }

            this.log.debug(http.getRequestMethod() + " " + url + (data != null ? " -> " + data : ""));
            if (http.getResponseCode() != 200) {
                this.log.warn("http responseCode: " + http.getResponseCode() + "-" + http.getResponseMessage() + "  url:" + url);
                if (msg != null) {
                    msg.append(http.getResponseCode() + "-" + http.getResponseMessage());
                }
            } else {
                InputStream is1 = http.getInputStream();
                char[] cc = new char[1024];
                BufferedReader br = new BufferedReader(new InputStreamReader(is1, "utf-8"));
                StringBuilder sb = new StringBuilder();

                int len;
                while ((len = br.read(cc)) != -1) {
                    sb.append(cc, 0, len);
                }

                br.close();
                this.log.debug("response: " + sb.toString());
                rep = sb.toString();
            }

            http.disconnect();
        } catch (Exception var12) {
            this.log.error("callUrl: " + url, var12);
            if (msg != null) {
                msg.append(var12.getClass().getName() + "-" + var12.getMessage());
            }
        }

        return rep;
    }

    private void addSignParam(Map<String, String> param) {
        ArrayList kl = new ArrayList();
        Iterator sb = param.keySet().iterator();

        String sign;
        String key;
        while (sb.hasNext()) {
            sign = (String) sb.next();
            key = (String) param.get(sign);
            if (key != null && key.length() > 0 && !"sign".equalsIgnoreCase(sign) && !"sign_type".equalsIgnoreCase(sign)) {
                kl.add(sign);
            }
        }

        Collections.sort(kl);
        StringBuilder sb1 = new StringBuilder();

        for (Iterator sign1 = kl.iterator(); sign1.hasNext(); sb1.append(key).append("=").append((String) param.get(key))) {
            key = (String) sign1.next();
            if (sb1.length() > 0) {
                sb1.append("&");
            }
        }

        sign = FuncUtil.Md5(sb1.toString() + this.getSetting("alipay.key"));
        param.put("sign", sign);
        param.put("sign_type", "MD5");
    }

    private String encode(String str) {
        if (str == null) {
            return "";
        } else {
            String encoded = "";
            try {
                encoded = URLEncoder.encode(str, "utf-8");
            } catch (Exception var6) {
                this.log.warn("encode:" + str, var6);
            }

            StringBuffer buf = new StringBuffer(encoded.length());

            for (int i = 0; i < encoded.length(); ++i) {
                char focus = encoded.charAt(i);
                if (focus == 42) {
                    buf.append("%2A");
                } else if (focus == 43) {
                    buf.append("%20");
                } else if (focus == 37 && i + 1 < encoded.length() && encoded.charAt(i + 1) == 55 && encoded.charAt(i + 2) == 69) {
                    buf.append('~');
                    i += 2;
                } else {
                    buf.append(focus);
                }
            }

            return buf.toString();
        }
    }

    protected String getSetting(String keyId) {
        return this.cache.getValue("setting", keyId);
    }
}
